home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 4 / FM Towns Free Software Collection 4 - Disc 1.iso / msdos / 3dmaze / 3dmaze.c next >
Text File  |  1991-10-18  |  12KB  |  449 lines

  1. /**********************************
  2.     3Dimensional maze
  3.     1991.04.31- 05.04
  4.      programming  H.Asano
  5. ***********************************/
  6.  
  7. #include <graph.h>
  8. #include <time.h>
  9.  
  10. #define locate(x,y)   printf("\x1b[%d;%dH",(x)+1,(y)+1)
  11. #define line(x1,y1,x2,y2)  { _moveto((x1),(y1)); _lineto((x2),(y2)); }
  12.  
  13. #define MX    21
  14. #define MY    37
  15. #define KABE   0         /* 壁   */
  16. #define MICHI  1         /* 道   */
  17. #define EXIT   2         /* 出口 */
  18. #define HINTMAX 6        /* 最大ヒント回数 */
  19. #define ON     1
  20. #define OFF    0
  21. #define REV   "\x1b[7m"
  22. #define RES   "\x1b[m"
  23.  
  24. static int map[MX][MY]; /* 迷路の配置を記憶 */
  25.  
  26. static int houkou     ; /* 方向  0:上  1:右  2:下  3:左 */
  27.  
  28.             /*上 右 下 左  */
  29. static int dx[4]      = {-1, 0, 1, 0};   /* 迷路のx方向変位 */
  30. static int dy[4]      = { 0, 1, 0,-1};   /* 迷路のy方向変位 */
  31. static int dlrx[2][4] = { 0,-1, 0, 1,    /* 左隣のx座標変位 */
  32.               0, 1, 0,-1};   /* 右隣のx座標変位 */
  33. static int dlry[2][4] = {-1, 0, 1, 0,    /* 左隣のy座標変位 */
  34.               1, 0,-1, 0};   /* 右隣のy座標変位 */
  35.  
  36. static int nowx,nowy;   /* 現在の位置 */
  37. static char c;          /* 入力キーコード */
  38. static int prtsu = 0;   /* ヒントの出力回数 */
  39. static int goalflg  ;
  40. static time_t starttime;
  41. static time_t keikatime;
  42. static time_t now;
  43. static int mm,ss;
  44.  
  45. static int fwd1x,fwd1y,fwd2x,fwd2y,fwd3x,fwd3y,
  46.        l0x,l0y,l1x,l1y,l2x,l2y,
  47.        r0x,r0y,r1x,r1y,r2x,r2y ;
  48.  
  49. void main(void)
  50. {
  51.   void init(void);
  52.   void graph(void);
  53.   void prt_maze(void);
  54.   void term(void);
  55.  
  56.      init();
  57.      
  58.      graph();
  59.      while(map[nowx][nowy] != EXIT) { /* 出口 まで */
  60.        c = getch();
  61.        switch(c) {
  62.      case 0x1b :    /* ESCキーが押されたら処理中断 */
  63.        _setvideomode(_DEFAULTMODE);
  64.        printf(RES);
  65.        exit(0);
  66.      case 0x1D :    /* ←  : 左を向く */
  67.        houkou = (houkou+3)%4;
  68.        break;
  69.      case 0x1C :    /* →  : 右を向く */
  70.        houkou = (houkou+1)%4;
  71.        break;
  72.      case 0x0d :    /* 実行キー */
  73.        if(!map[nowx+dx[houkou]][nowy+dy[houkou]]) {  /* 壁で進めない */
  74.          printf("\a"); /* beep音 */
  75.          break;
  76.        }
  77.        nowx += dx[houkou];    /* 前進 */
  78.        nowy += dy[houkou];
  79.        break;
  80.      case 'h' :    /* h,Hキー (Help) : 地図を出力 */
  81.      case 'H' :
  82.        prt_maze();
  83.            break;
  84.          default :
  85.            continue;
  86.        }
  87.        graph();  
  88.      }
  89.  
  90.      term();
  91. }
  92.  
  93. void init(void)
  94. {
  95.   void make_maze(int,int);
  96.   int  get_rand(int);
  97.  
  98.      _setvideomode(_FMRESSCOLOR); /* グラフィック & TEXT モード */
  99.      _setvieworg(50,50);          /* 原点を移動          */
  100.      _displaycursor(_GCURSOROFF); /* カーソル OFF        */
  101.      srand(time(&now));           /* 乱数列 初期化       */
  102.      make_maze(1,1);              /* 迷路の作成          */
  103.      map[MX-1][MY-2] = EXIT;      /* 出口                */
  104.      do {                         /* 最初の位置          */
  105.        nowx = get_rand(MX-1);
  106.        nowy = get_rand(MY-1);
  107.      } while(!map[nowx][nowy]) ;
  108.      houkou    = get_rand(4);     /* 最初の方向          */
  109.      starttime = time(&now);      /* 始まりの時間を記録  */
  110.  
  111. }
  112.  
  113. void make_maze(int x,int y)
  114. {
  115.  
  116.   int i;
  117.   int xx,yy;
  118.   int sum=0;
  119.   int work[] = {0,0,0,0};
  120.  
  121.      for(;;) {
  122.        work[i=get_rand(4)]++;
  123.        xx = x+dx[i]*2;
  124.        yy = y+dy[i]*2;
  125.        if((0<=xx) && (xx<=MX-1) && (0<=yy) && (yy<=MY-1) && (!map[xx][yy]))
  126.       break ;        /* 迷路内で道が出来ていない場所ならOK */
  127.        else              /* 行けない場所だったらワークに記憶   */
  128.      if((work[i]==1) && (++sum==4)) return; /* 行き止まりならリターン */
  129.      }
  130.      map[x][y] = MICHI;
  131.      map[x+dx[i]][y+dy[i]] = MICHI;
  132.      map[xx][yy] = MICHI;
  133.  
  134.      if((xx != MX-2) || (yy != MY-2))  make_maze(xx,yy);
  135.      make_maze(x,y);
  136.      return;
  137. }
  138.  
  139. void prt_maze()
  140. {
  141.   int x,y;
  142.   long w;
  143.  
  144.      if(prtsu >= HINTMAX) return; /* 最大ヒント回数以上はリターン */
  145.      prtsu++;
  146.      _clearscreen(_GCLEARGRAPH);  /* グラフィックのクリア */
  147.      locate(3,0);
  148.      for(x=0;x<MX;x++) {
  149.        for(y=0;y<MY;y++) {
  150.      if(x==nowx && y==nowy) {
  151.        printf(REV);
  152.        switch(houkou) {
  153.          case  0 :
  154.            printf("\x1b[36m↑\x1b[m");
  155.            break;
  156.          case  1 :
  157.            printf("\x1b[36m→\x1b[m");
  158.            break;
  159.          case  2 :
  160.            printf("\x1b[36m↓\x1b[m");
  161.            break;
  162.          case 3 :
  163.            printf("\x1b[36m←\x1b[m");
  164.            break;
  165.        }
  166.      }
  167.      else if(!map[x][y]) {  /* 壁 */
  168.        printf(REV);
  169.        printf("  ");
  170.      }
  171.      else {                 /* 道,出口 */
  172.        printf(RES);
  173.        printf("  ");
  174.      }
  175.        }
  176.        printf(RES);
  177.        printf("\n");
  178.      }
  179.      for(w=0;w<400000;w++) x=y; /* 時間かせぎ */
  180.      _clearscreen(_GCLEARSCREEN);
  181. }
  182.  
  183. void term(void)
  184. {
  185.      _setvideomode(_DEFAULTMODE);
  186.      keikatime = time(&now) - starttime;
  187.      mm = keikatime / 60;
  188.      ss = keikatime % 60;
  189.      printf(RES);
  190.      locate(2,5);
  191.      printf("おめでとうございます。\n");
  192.      printf("      通過時間は %d分%d秒 でした。\n\n",mm,ss);
  193. }
  194.  
  195. int get_rand(int max)   /* max未満の乱数を返します */
  196. {
  197.   int temp;
  198.  
  199.      do {
  200.        temp = rand() / (32767/max);
  201.      } while(temp >= max);
  202.      return(temp);
  203. }
  204.  
  205. void graph(void)
  206. {
  207.   void graphk0(void),graphk1(void),graphk2(void),
  208.        graphm0(void),graphm1(void),graphm2(void),
  209.        clear(void)  ;
  210.  
  211.      if(goalflg) {  /* 画面にゴール印が表示されていたらクリア */
  212.        clear();
  213.        goalflg=OFF;
  214.      }
  215.      _clearscreen(_GCLEARGRAPH);
  216.      locate(0,5);
  217.      printf(" ** 3 Dimensional Maze  [V1.0] **   Copyright (c) 1991 H.Asano\n");
  218.      keikatime   = time(&now) - starttime;
  219.      mm = keikatime / 60;
  220.      ss = keikatime % 60;
  221.      printf("\n         経過時間 = %2d分%2d秒",mm,ss);
  222.      printf("    残りヒント回数 = %d\n" ,HINTMAX-prtsu);
  223.      _rectangle(_GBORDER,0,0,500,300);    /* 枠を描く     */
  224.  
  225.      fwd1x = nowx  + dx[houkou];
  226.      fwd1y = nowy  + dy[houkou];
  227.      fwd2x = fwd1x + dx[houkou];
  228.      fwd2y = fwd1y + dy[houkou];
  229.      fwd3x = fwd2x + dx[houkou];
  230.      fwd3y = fwd2y + dy[houkou];
  231.      l0x   = nowx  + dlrx[0][houkou];
  232.      l0y   = nowy  + dlry[0][houkou];
  233.      r0x   = nowx  + dlrx[1][houkou];
  234.      r0y   = nowy  + dlry[1][houkou];
  235.      l1x   = fwd1x + dlrx[0][houkou];
  236.      l1y   = fwd1y + dlry[0][houkou];
  237.      r1x   = fwd1x + dlrx[1][houkou];
  238.      r1y   = fwd1y + dlry[1][houkou];
  239.      l2x   = fwd2x + dlrx[0][houkou];
  240.      l2y   = fwd2y + dlry[0][houkou];
  241.      r2x   = fwd2x + dlrx[1][houkou];
  242.      r2y   = fwd2y + dlry[1][houkou];
  243.  
  244.      if((map[fwd1x][fwd1y]==KABE) || (map[fwd1x][fwd1y]==EXIT)) {
  245.        graphk0();
  246.      }
  247.      else if((map[fwd2x][fwd2y]==KABE) || (map[fwd2x][fwd2y]==EXIT)) {
  248.        graphk1();
  249.        graphm0();
  250.      }
  251.      else if((map[fwd3x][fwd3y]==KABE) || (map[fwd3x][fwd3y]==EXIT)) {
  252.        graphk2();
  253.        graphm1();
  254.        graphm0();
  255.      }
  256.      else {
  257.        graphm2();
  258.        graphm1();
  259.        graphm0();
  260.     }
  261. }
  262.  
  263. void graphk0(void)
  264. {
  265.      line( 60, 36,440, 36);
  266.      line( 60,264,440,264);
  267.  
  268.      if(map[l0x][l0y]) {     /* 左側が道 */
  269.        line(  0, 36, 60, 36);
  270.        line(  0,264, 60,264);
  271.      }
  272.      else {                  /* 左側が壁 */
  273.        line(  0,  0, 60, 36);
  274.        line( 60, 36, 60,264);
  275.        line( 60,264,  0,300);
  276.      }
  277.      if(map[r0x][r0y]) {     /* 右側が道 */
  278.        line(440, 36,500, 36);
  279.        line(440,264,500,264);
  280.      }
  281.      else {                  /* 右側が壁 */
  282.        line(500,  0,440, 36);
  283.        line(440, 36,440,264);
  284.        line(440,264,500,300);
  285.      }
  286.      if(map[fwd1x][fwd1y]==EXIT) {
  287.        goalflg = ON ;
  288.        printf("\x1b[7m");
  289.        locate( 9,25); printf("                         ");
  290.        locate(10,25); printf("                         ");
  291.        locate(11,25); printf("                         ");
  292.        locate(12,25); printf("         G O A L         ");
  293.        locate(13,25); printf("                         ");
  294.        locate(14,25); printf("                         ");
  295.        locate(15,25); printf("                         \x1b[m");
  296.      }
  297. }
  298.  
  299. void graphm0(void)
  300. {
  301.       if(map[l0x][l0y]) {
  302.     line(  0, 36, 60, 36);
  303.     line( 60, 36, 60,264);
  304.     line( 60,264,  0,264);
  305.       }
  306.       else {
  307.     line(  0,  0, 60, 36);
  308.     line( 60,264,  0,300);
  309.       }
  310.       if(map[r0x][r0y]) {
  311.     line(500, 36,440, 36);
  312.     line(440, 36,440,264);
  313.     line(440,264,500,264);
  314.       }
  315.       else {
  316.     line(500,  0,440, 36);
  317.     line(440,264,500,300);
  318.       }
  319. }
  320.  
  321. void graphk1(void)
  322. {
  323.      line(150, 90,350, 90);
  324.      line(150,214,350,214);
  325.  
  326.      if(map[l1x][l1y]) {
  327.        line( 60, 90,150, 90);
  328.        line( 60,214,150,214);
  329.        line( 60, 36, 60,264);
  330.      }
  331.      else {
  332.        line( 60, 36,150, 90);
  333.        line(150, 90,150,214);
  334.        line(150,214, 60,264);
  335.      }
  336.      if(map[r1x][r1y]) {
  337.        line(440, 90,350, 90);
  338.        line(440, 36,440,264);
  339.        line(440,214,350,214);
  340.      }
  341.      else {
  342.        line(440, 36,350, 90);
  343.        line(350, 90,350,214);
  344.        line(350,214,440,264);
  345.      }
  346.      if(map[fwd2x][fwd2y]==EXIT) {
  347.        goalflg = ON;
  348.        printf("\x1b[7m");
  349.        locate(11,30); printf("               ");
  350.        locate(12,30); printf("    G O A L    ");
  351.        locate(13,30); printf("               \x1b[m");
  352.      }
  353. }
  354.  
  355. void graphm1(void)
  356. {
  357.      if(map[l1x][l1y]) {
  358.        line( 60, 36, 60,264);
  359.        line( 60, 90,150, 90);
  360.        line(150, 90,150,214);
  361.        line(150,214, 60,214);
  362.      }
  363.      else {
  364.        line( 60, 36,150, 90);
  365.        line( 60,264,150,214);
  366.      }
  367.      if(map[r1x][r1y]) {
  368.        line(440, 36,440,264);
  369.        line(440, 90,350, 90);
  370.        line(350, 90,350,214);
  371.        line(350,214,440,214);
  372.      }
  373.      else {
  374.        line(440, 36,350, 90);
  375.        line(440,264,350,214);
  376.      }
  377. }
  378.  
  379. void graphk2(void)
  380. {
  381.      line(210,126,290,126);
  382.      line(210,176,290,176);
  383.  
  384.      if(map[l2x][l2y]) {
  385.        line(150, 90,150,214);
  386.        line(150,126,210,126);
  387.        line(150,176,210,176);
  388.      }
  389.      else {
  390.        line(150, 90,210,126);
  391.        line(210,126,210,176);
  392.        line(210,176,150,214);
  393.      }
  394.      if(map[r2x][r2y]) {
  395.        line(350, 90,350,214);
  396.        line(350,126,290,126);
  397.        line(350,176,290,176);
  398.      }
  399.      else {
  400.        line(350, 90,290,126);
  401.        line(290,126,290,176);
  402.        line(290,176,350,214);
  403.      }
  404.      if(map[fwd3x][fwd3y]==EXIT) {
  405.        goalflg = ON;
  406.        locate(12,34);
  407.        printf("\x1b[7mG O A L\x1b[m");
  408.      }
  409. }
  410.  
  411. void graphm2(void)
  412. {
  413.      line(210,126,290,176);
  414.      line(290,126,210,176);
  415.  
  416.      if(map[l2x][l2y]) {
  417.        line(150, 90,150,214);
  418.        line(150,126,210,126);
  419.        line(210,126,210,176);
  420.        line(210,176,150,176);
  421.      }
  422.      else {
  423.        line(150, 90,210,126);
  424.        line(210,176,150,214);
  425.      }
  426.      if(map[r2x][r2y]) {
  427.        line(350, 90,350,214);
  428.        line(350,126,290,126);
  429.        line(290,126,290,176);
  430.        line(290,176,350,176);
  431.      }
  432.      else {
  433.        line(350, 90,290,126);
  434.        line(290,176,350,214);
  435.      }
  436. }
  437.  
  438. void clear(void)
  439. {
  440.        printf(RES);
  441.        locate( 9,25); printf("                         ");
  442.        locate(10,25); printf("                         ");
  443.        locate(11,25); printf("                         ");
  444.        locate(12,25); printf("                         ");
  445.        locate(13,25); printf("                         ");
  446.        locate(14,25); printf("                         ");
  447.        locate(15,25); printf("                         ");
  448. }
  449.